package org.txazo.music.commons.lrc;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.txazo.music.util.DescComparator;

/**
 * 搜索LRC歌词
 * 
 * @author Tu XiaoZhou
 * @since 2013-04-12
 * 
 */
public class SearchLRC {

	private static final String LRC_SEARCH_URL = "http://www.9ilrc.com/search.php";
	private static final String LRC_SEARCH_KEYWORD = "?keyword=";
	private static final String LRC_SEARCH_RADIO = "&radio=song";
	private static final String LRC_SEARCH_PAGE = "&page=";
	private static final String STRING_TAG_SPAN = "<span>";
	private static final String STRING_DIV_LEFT = "<div class=\"left\">";
	private static final String STRING_DIV_RIGHT = "<div class=\"right\">";
	private static final String STRING_HTML_1 = "<td";
	private static final String STRING_HTML_2 = "<td class=\"gm\">";
	private static final String STRING_HTML_3 = "<tr class=page>";
	private static final String STRING_HTML_4 = "&page=";
	private static final String STRING_DOUBLE_QUOTE = "\"";
	private static final String STRING_TAG_TD = "<td>";
	private static final String STRING_TAG_TD_END = "</td>";

	public static String getUrl(String title, int page) {
		StringBuilder sb = new StringBuilder(50);
		sb.append(LRC_SEARCH_URL);
		sb.append(LRC_SEARCH_KEYWORD);
		sb.append(title);
		sb.append(LRC_SEARCH_RADIO);

		if (page > 1) {
			sb.append(LRC_SEARCH_PAGE);
			sb.append(page);
		}

		return sb.toString();
	}

	public static LRC getLRC(String title, String artist) {
		return getLRC(title, artist, 1);
	}

	public static LRC getLRC(String title, String artist, int page) {
		List<LRC> list = getLRCList(title, artist, page);

		if (list.size() > 0) {
			Map<Integer, LRC> map = new HashMap<Integer, LRC>();
			for (LRC lrc : list) {
				map.put(lrc.getDownloads(), lrc);
			}

			Map<Integer, LRC> treeMap = new TreeMap<Integer, LRC>(
					new DescComparator());
			treeMap.putAll(map);

			return new ArrayList<LRC>(treeMap.values()).get(0);
		}

		return null;
	}

	public static List<LRC> getLRCList(String title, String artist, int page) {
		BufferedReader br = null;
		boolean flag = false;
		boolean end = true;
		boolean first = true;
		int count = 0;
		LRC lrc = null;
		List<LRC> list = new ArrayList<LRC>();
		try {
			URL url = new URL(getUrl(title, page));
			br = new BufferedReader(new InputStreamReader(url.openStream()));
			String temp = null;
			while ((temp = br.readLine()) != null && end) {
				temp = temp.trim();
				if (temp.startsWith(STRING_DIV_LEFT)) {
					flag = true;
				} else if (temp.startsWith(STRING_DIV_RIGHT)) {
					flag = false;
					end = false;
				}
				if (flag) {
					if (temp.startsWith(STRING_HTML_1)) {
						if (temp.startsWith(STRING_HTML_2)) {
							if (first) {
								count = 0;
								first = false;
							}
							if (getTitle(temp).equals(title)) {
								lrc = new LRC();
								lrc.setTitle(title);
							}
						} else if (count % 9 == 2 && lrc != null) {
							if (getArtist(temp).equals(artist)) {
								lrc.setArtist(artist);
							} else {
								lrc = null;
							}
						} else if (count % 9 == 4 && lrc != null) {
							lrc.setDownloads(getDownloads(temp));
						} else if (count % 9 == 6 && lrc != null) {
							lrc.setUrl(getLRCUrl(temp));
						}

						if (count % 9 == 8 && lrc != null) {
							list.add(lrc);
							lrc = null;
						}

						count++;
					} else if (temp.startsWith(STRING_HTML_3)) {
						if (temp.contains(STRING_TAG_SPAN)
								&& temp.split(STRING_TAG_SPAN)[1]
										.contains(STRING_HTML_4)) {
							list.addAll(getLRCList(title, artist, page + 1));
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		return list;
	}

	public static String getTitle(String str) {
		return str.split(STRING_DOUBLE_QUOTE)[3];
	}

	public static String getArtist(String str) {
		return str.split(STRING_DOUBLE_QUOTE)[1];
	}

	public static int getDownloads(String str) {
		return Integer.valueOf(str.split(STRING_TAG_TD)[1]
				.split(STRING_TAG_TD_END)[0]);
	}

	public static String getLRCUrl(String str) {
		return str.split(STRING_DOUBLE_QUOTE)[3];
	}

}
